<template>
  <canvas 
    v-if="showCanvas"
    canvas-id="posterCanvas" 
    id="posterCanvas"
    :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
    class="poster-canvas"
  ></canvas>
</template>

<script>
export default {
  name: 'PosterCanvas',
  props: {
    type: {
      type: String,
      default: 'warehouse',
      validator: value => ['warehouse', 'park'].includes(value)
    },
    data: {
      type: Object,
      default: () => ({})
    },
    showCanvas: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 完全匹配 PosterModal 中的 poster-content 尺寸
      canvasWidth: 652, // 对应 poster-content 的 width: 652rpx
      canvasHeight: 890, // 对应 poster-content 的 height: 954rpx
      ctx: null,
      imageCache: new Map() // 图片缓存
    }
  },
  methods: {
    // 生成海报 - 一比一复制 poster-content 的所有元素
    async generatePoster() {
      try {
        console.log('=== PosterCanvas 开始生成海报 ===')
        console.log('PosterCanvas - 接收到的数据:', JSON.stringify(this.data, null, 2))
        console.log('PosterCanvas - 类型:', this.type)
        console.log('PosterCanvas - showCanvas:', this.showCanvas)
        
        await this.$nextTick()
        
        const ctx = uni.createCanvasContext('posterCanvas', this)
        this.ctx = ctx
        
        console.log('Canvas尺寸设置:', this.canvasWidth, 'x', this.canvasHeight)
        
        // 清空画布
        ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
        
        // 1. 绘制背景图片 (poster-bg-image)
        await this.drawBackgroundImage(ctx)
        
        // 2. 绘制海报卡片 (poster-card-wrapper)
        await this.drawPosterCard(ctx)
        
        // 绘制完成
        ctx.draw(false, () => {
          console.log('=== 海报绘制完成 ===')
          this.$emit('poster-generated')
        })
        
      } catch (error) {
        console.error('生成海报失败:', error)
        this.$emit('error', error)
      }
    },
    
    // 绘制背景图片 - 匹配 poster-bg-image
    async drawBackgroundImage(ctx) {
      try {
        // 背景图片尺寸: 100% x 100%，圆角 16rpx
        await this.drawImageWithFallback(
          ctx, 
          '/static/assets/source/post-bg.png', 
          0, 0, 
          this.canvasWidth, 
          this.canvasHeight
        )
      } catch (error) {
        console.warn('背景图片绘制失败:', error)
        // 绘制默认背景
        ctx.setFillStyle('#f0f0f0')
        this.drawRoundedRect(ctx, 0, 0, this.canvasWidth, this.canvasHeight, 16)
        ctx.fill()
      }
    },
    
    // 绘制海报卡片 - 匹配 poster-card-wrapper
    async drawPosterCard(ctx) {
      // poster-card-wrapper 位置: top: 20rpx, right: 0, width: 620rpx, height: 920rpx
      const cardX = this.canvasWidth - 620 // right: 0 表示右对齐
      const cardY = 20 // top: 20rpx
      const cardWidth = 620
      const cardHeight = 860
      
      // 绘制卡片背景和阴影
      this.drawRoundedRect(ctx, cardX, cardY, cardWidth, cardHeight, 16)
      ctx.setFillStyle('#ffffff')
      ctx.fill()
      
      // 绘制卡片内容 (poster-card)
      await this.drawCardContent(ctx, cardX, cardY, cardWidth, cardHeight)
    },
    
    // 绘制卡片内容 - 匹配 poster-card
    async drawCardContent(ctx, cardX, cardY, cardWidth, cardHeight) {
      // poster-card 的 padding: 20rpx
      const padding = 20
      let currentY = cardY + padding
      
      // 1. 绘制图片 (poster-image)
      const imageUrl = this.getImageUrl()
      if (imageUrl) {
        try {
          // poster-image: width: 100%, height: 200rpx, border-radius: 12rpx, margin-bottom: 20rpx
          const imageWidth = cardWidth - padding * 2
          const imageHeight = 200
          await this.drawImageWithFallback(ctx, imageUrl, cardX + padding, currentY, imageWidth, imageHeight)
          currentY += imageHeight + 20 // margin-bottom: 20rpx
        } catch (error) {
          console.warn('图片绘制失败，使用默认图片:', error)
          this.drawImagePlaceholder(ctx, cardX + padding, currentY, cardWidth - padding * 2, 200)
          currentY += 200 + 20
        }
      }
      
      // 2. 绘制信息区域 (poster-info)
      // poster-info 的 padding: 0 10rpx
      const infoX = cardX + padding + 10
      const infoWidth = cardWidth - padding * 2 - 20
      
      // 2.1 绘制标题 (title)
      // 向下便宜 10px
      const title = this.getTitle()
      ctx.setFillStyle('#333333')
      ctx.setFontSize(32)
      ctx.setTextAlign('left')
      const titleOffsetY = 20 // 标题向下便宜10px
      const titleEndY = this.drawTextWithWrap(ctx, title, infoX, currentY + titleOffsetY, infoWidth, 32, '#333333')
      currentY = titleEndY + 12 // margin-bottom: 12rpx
      
      // 2.2 绘制地址信息 (address-row)
      const address = this.getAddress()
      // 绘制位置图标
      try {
        await this.drawImageWithFallback(
          ctx, 
          '/static/assets/parkInfo/park-info-row5.png', 
          infoX, 
          currentY-25, 
          18, 
          24
        )
      } catch (error) {
        console.warn('位置图标绘制失败:', error)
      }
      
      // 绘制地址文字
      ctx.setFillStyle('#666666')
      ctx.setFontSize(24)
      const addressEndY = this.drawTextWithWrap(
        ctx, 
        address, 
        infoX + 18 + 8, // location-icon width + margin-right: 8rpx
        currentY, 
        infoWidth - 18 - 8, 
        24, 
        '#666666'
      )
      currentY = addressEndY + 16 // margin-bottom: 16rpx
      
      // 2.3 绘制价格信息 (price-row)
      if (this.type === 'warehouse' || this.type === 'park') {
        const price = this.getPrice()
        const area = this.getArea()
        
        // 价格文字 (price-text)
        ctx.setFillStyle('#C02C38')
        ctx.setFontSize(28)
        ctx.fillText(`¥${price}元/m²/天`, infoX, currentY)
        
        // 价格提示 (price-tip)
        ctx.setFillStyle('#999999')
        ctx.setFontSize(20)
        const priceTextWidth = ctx.measureText(`¥${price}元/m²/天`).width
        ctx.fillText('起(具体面议)', infoX + priceTextWidth + 80, currentY) // margin-right: 8rpx
        
        // 招租面积 (rentable-area)
        const tipTextWidth = ctx.measureText(`起(具体面议)`).width

        ctx.setFillStyle('#666666')
        ctx.setFontSize(22)
        ctx.fillText(`招租面积: ${this.formatArea(area)}`, infoX + priceTextWidth+tipTextWidth + 80, currentY)
        currentY += 28 // 价格行高度 + 招租面积行高度 + margin-bottom: 20rpx
      }
      
      // 3. 绘制园区规模卡片 (uni-card)
      await this.drawDetailCard(ctx, infoX, currentY, infoWidth)
    },
    
    // 绘制详细信息卡片 - 匹配 uni-card
    async drawDetailCard(ctx, x, y, width) {
      // uni-card 的 padding: 10rpx, margin: 0rpx
      const cardPadding = 10
      const cardX = x - cardPadding
      const cardY = y
      const cardWidth = width + cardPadding * 2
      
      // 3.1 绘制园区规模标题 (card-header)
      // 绘制图标
      try {
        await this.drawImageWithFallback(
          ctx, 
          '/static/assets/parkInfo/park-info-row1.png', 
          cardX + cardPadding, 
          cardY + cardPadding, 
          18, 
          23
        )
      } catch (error) {
        console.warn('园区规模图标绘制失败:', error)
      }
      
      // 绘制标题文字
      ctx.setFillStyle('#333333')
      ctx.setFontSize(24)
      ctx.fillText('园区规模', cardX + cardPadding + 18 + 8, cardY + cardPadding + 20) // margin-right: 8rpx
      
      let currentY = cardY + cardPadding + 24 + 20 // 标题高度 + margin-top: 20rpx
      
      // 3.2 绘制详细信息网格 (detail-section)
      const detailItems = this.getDetailItems()
      if (detailItems && detailItems.length > 0) {
        // detail-grid: grid-template-columns: 1fr 1fr, gap: 16rpx
        const itemWidth = (cardWidth - cardPadding * 2 - 16) / 2 // gap: 16rpx
        const itemHeight = 80 // 估算高度

        // 文字排版参数
        const labelFontSize = 20
        const valueFontSize = 24
        const verticalGap = 10 // label和value之间的间距
        const paddingY = 12 // 上下内边距

        detailItems.forEach((item, index) => {
          const row = Math.floor(index / 2)
          const col = index % 2
          const itemX = cardX + cardPadding + col * (itemWidth + 16) // gap: 16rpx
          const itemY = currentY + row * (itemHeight + 16) // gap: 16rpx

          // 绘制详情项背景 (detail-item)
          this.drawRoundedRect(ctx, itemX, itemY, itemWidth, itemHeight, 8) // border-radius: 8rpx
          ctx.setFillStyle('#f8f9fa') // background: #f8f9fa
          ctx.fill()

          // 绘制边框
          ctx.setStrokeStyle('#e9ecef')
          ctx.setLineWidth(1)
          ctx.stroke()

          // 计算内容区高度和起始Y，实现内容垂直居中
          // label高度 + 间距 + value高度
          const contentHeight = labelFontSize + verticalGap + valueFontSize
          const contentStartY = itemY + (itemHeight - contentHeight) / 2

          // 绘制标签 (detail-label)
          ctx.setFillStyle('#666666')
          ctx.setFontSize(labelFontSize)
          ctx.fillText(item.label, itemX + 16, contentStartY + labelFontSize)

          // 绘制值 (detail-value)
          ctx.setFillStyle('#333333')
          ctx.setFontSize(valueFontSize)
          // value的Y = label的Y + labelFontSize + verticalGap
          this.drawTextWithWrap(
            ctx,
            item.value,
            itemX + 16,
            contentStartY + labelFontSize + verticalGap + valueFontSize,
            itemWidth - 32,
            valueFontSize,
            '#333333'
          )
        })

        currentY += Math.ceil(detailItems.length / 2) * (itemHeight + 16) + 20
      }
      
      // 3.3 绘制联系人信息卡片 (第二个 uni-card)
      // 绘制图标
      try {
        await this.drawImageWithFallback(
          ctx, 
          '/static/assets/parkInfo/park-info-row1.png', 
          cardX + cardPadding, 
          currentY + cardPadding, 
          18, 
          23
        )
      } catch (error) {
        console.warn('联系人图标绘制失败:', error)
      }
      
      // 绘制联系人文字
      const manager = this.data.manager || this.data.parkInfo?.manager || '-'
      const contactPhone = this.data.contactPhone || this.data.parkInfo?.contactPhone || '-'
      const contactText = `招商联系人：${manager} ${contactPhone}`
      ctx.setFillStyle('#333333')
      ctx.setFontSize(24)
      this.drawTextWithWrap(
        ctx, 
        contactText, 
        cardX + cardPadding + 18 + 8, 
        currentY + cardPadding + 20, 
        cardWidth - cardPadding * 2 - 18 - 8, 
        24, 
        '#333333'
      )
    },
    
    // 绘制图片（带回退机制）
    async drawImageWithFallback(ctx, imageUrl, x, y, width, height) {
      return new Promise((resolve, reject) => {
        console.log('开始绘制图片:', imageUrl, '位置:', x, y, '尺寸:', width, height)
        
        // 检查缓存
        if (this.imageCache.has(imageUrl)) {
          const cachedImage = this.imageCache.get(imageUrl)
          console.log('使用缓存图片:', cachedImage)
          ctx.drawImage(cachedImage, x, y, width, height)
          resolve()
          return
        }
        
        // 判断是否为本地图片
        const isLocalImage = imageUrl.startsWith('/static/') || 
                           imageUrl.startsWith('@/static/') || 
                           imageUrl.startsWith('./static/') ||
                           !imageUrl.startsWith('http')
        
        if (isLocalImage) {
          // 本地图片直接绘制
          let localPath = imageUrl
          if (imageUrl.startsWith('@/static/')) {
            localPath = imageUrl.replace('@/', '/')
          }
          
          console.log('绘制本地图片:', localPath)
          try {
            ctx.drawImage(localPath, x, y, width, height)
            // 缓存本地图片路径
            this.imageCache.set(imageUrl, localPath)
            console.log('本地图片绘制成功')
            resolve()
          } catch (error) {
            console.error('本地图片绘制失败:', error)
            reject(error)
          }
        } else {
          // 网络图片需要下载
          console.log('下载网络图片:', imageUrl)
          uni.downloadFile({
            url: imageUrl,
            success: (res) => {
              console.log('图片下载结果:', res)
              if (res.statusCode === 200 && res.tempFilePath) {
                // 缓存图片
                this.imageCache.set(imageUrl, res.tempFilePath)
                console.log('图片下载成功，开始绘制:', res.tempFilePath)
                
                // 绘制图片
                ctx.drawImage(res.tempFilePath, x, y, width, height)
                console.log('图片绘制完成')
                resolve()
              } else {
                console.error('图片下载失败，状态码:', res.statusCode)
                reject(new Error(`图片下载失败: ${res.statusCode}`))
              }
            },
            fail: (error) => {
              console.error('图片下载失败:', error)
              reject(error)
            }
          })
        }
      })
    },
    
    // 绘制图片占位符
    drawImagePlaceholder(ctx, x, y, width, height) {
      // 绘制灰色背景
      ctx.setFillStyle('#f5f5f5')
      this.drawRoundedRect(ctx, x, y, width, height, 12) // 匹配 border-radius: 12rpx
      ctx.fill()
      
      // 绘制边框
      ctx.setStrokeStyle('#e0e0e0')
      ctx.setLineWidth(2)
      ctx.stroke()
      
      // 绘制占位符文字
      ctx.setFillStyle('#999999')
      ctx.setFontSize(24)
      ctx.setTextAlign('center')
      ctx.fillText('图片加载失败', x + width / 2, y + height / 2)
      ctx.setTextAlign('left')
    },
    
    // 绘制带换行的文本
    drawTextWithWrap(ctx, text, x, y, maxWidth, fontSize, color) {
      if (!text) return y
      
      ctx.setFillStyle(color)
      ctx.setFontSize(fontSize)
      ctx.setTextAlign('left')
      
      const words = text.split('')
      let line = ''
      let currentY = y
      const lineHeight = fontSize * 1.2
      
      for (let i = 0; i < words.length; i++) {
        const testLine = line + words[i]
        const metrics = ctx.measureText(testLine)
        
        if (metrics.width > maxWidth && line !== '') {
          ctx.fillText(line, x, currentY)
          line = words[i]
          currentY += lineHeight
        } else {
          line = testLine
        }
      }
      
      if (line) {
        ctx.fillText(line, x, currentY)
        currentY += lineHeight
      }
      
      return currentY
    },
    
    // 绘制圆角矩形
    drawRoundedRect(ctx, x, y, width, height, radius) {
      ctx.beginPath()
      ctx.moveTo(x + radius, y)
      ctx.lineTo(x + width - radius, y)
      ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
      ctx.lineTo(x + width, y + height - radius)
      ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
      ctx.lineTo(x + radius, y + height)
      ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
      ctx.lineTo(x, y + radius)
      ctx.quadraticCurveTo(x, y, x + radius, y)
      ctx.closePath()
    },
    
    // 绘制关闭按钮 - 匹配 close-btn
    async drawCloseButton(ctx, cardX, cardY, cardWidth, cardHeight) {
      try {
        // close-btn 位置计算：
        // poster-card-wrapper: top: 20rpx, right: 0, width: 620rpx
        // close-btn: top: -25rpx, right: -25rpx, width: 85rpx, height: 85rpx
        // 所以关闭按钮的实际位置是：
        // X: cardX + cardWidth - 85 - 25 (right: -25rpx 表示从右边界向左25rpx)
        // Y: cardY - 25 (top: -25rpx 表示从上边界向上25rpx)
        const closeBtnX = cardX + cardWidth - 85 - 25 // right: -25rpx
        const closeBtnY = cardY - 25 // top: -25rpx
        const closeBtnSize = 85
        
        console.log('开始绘制关闭按钮，位置:', closeBtnX, closeBtnY, '尺寸:', closeBtnSize)
        await this.drawImageWithFallback(
          ctx, 
          '/static/assets/source/postTopIcon.png', 
          closeBtnX, 
          closeBtnY, 
          closeBtnSize, 
          closeBtnSize
        )
        console.log('关闭按钮绘制成功')
      } catch (error) {
        console.warn('关闭按钮绘制失败:', error)
        // 绘制默认关闭按钮
        this.drawCloseButtonPlaceholder(ctx, cardX, cardY, cardWidth, cardHeight)
      }
    },
    
    // 绘制关闭按钮占位符
    drawCloseButtonPlaceholder(ctx, cardX, cardY, cardWidth, cardHeight) {
      // 位置计算与上面一致
      const closeBtnX = cardX + cardWidth - 85 - 25
      const closeBtnY = cardY - 25
      const closeBtnSize = 85
      
      // 绘制圆形背景
      ctx.beginPath()
      ctx.arc(closeBtnX + closeBtnSize / 2, closeBtnY + closeBtnSize / 2, closeBtnSize / 2, 0, 2 * Math.PI)
      ctx.setFillStyle('#ffffff')
      ctx.fill()
      
      // 绘制边框
      ctx.setStrokeStyle('#e0e0e0')
      ctx.setLineWidth(2)
      ctx.stroke()
      
      // 绘制 X 符号
      ctx.setStrokeStyle('#999999')
      ctx.setLineWidth(3)
      const centerX = closeBtnX + closeBtnSize / 2
      const centerY = closeBtnY + closeBtnSize / 2
      const crossSize = 20
      
      // 绘制 X 的两条线
      ctx.beginPath()
      ctx.moveTo(centerX - crossSize / 2, centerY - crossSize / 2)
      ctx.lineTo(centerX + crossSize / 2, centerY + crossSize / 2)
      ctx.moveTo(centerX + crossSize / 2, centerY - crossSize / 2)
      ctx.lineTo(centerX - crossSize / 2, centerY + crossSize / 2)
      ctx.stroke()
    },
    
    // 保存到相册 - 增强版本
    saveToAlbum() {
      // 检查权限
      uni.getSetting({
        success: (res) => {
          if (res.authSetting['scope.writePhotosAlbum'] === false) {
            // 用户之前拒绝了权限，引导用户手动开启
            uni.showModal({
              title: '需要相册权限',
              content: '保存图片需要访问您的相册，请在设置中开启权限',
              confirmText: '去设置',
              success: (modalRes) => {
                if (modalRes.confirm) {
                  uni.openSetting()
                }
              }
            })
            return
          }
          
          // 开始保存流程
          this.performSave()
        },
        fail: () => {
          // 直接尝试保存
          this.performSave()
        }
      })
    },
    
    // 执行保存操作
    performSave() {
      uni.showLoading({
        title: '生成中...',
        mask: true
      })
      
      uni.canvasToTempFilePath({
        canvasId: 'posterCanvas',
        fileType: 'png',
        quality: 1,
        success: (res) => {
          console.log('Canvas转图片成功:', res.tempFilePath)
          uni.hideLoading()
          
          // 保存到相册
          uni.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success: () => {
              console.log('保存到相册成功')
              uni.showToast({
                title: '保存成功',
                icon: 'success',
                duration: 2000
              })
              this.$emit('saved')
            },
            fail: (error) => {
              console.error('保存到相册失败:', error)
              this.handleSaveError(error)
            }
          })
        },
        fail: (error) => {
          console.error('Canvas转图片失败:', error)
          uni.hideLoading()
          this.handleSaveError(error)
        }
      }, this)
    },
    
    // 处理保存错误
    handleSaveError(error) {
      if (error.errMsg && error.errMsg.includes('auth deny')) {
        uni.showModal({
          title: '权限不足',
          content: '需要授权保存图片到相册，请在设置中开启权限',
          confirmText: '去设置',
          success: (res) => {
            if (res.confirm) {
              uni.openSetting()
            }
          }
        })
      } else {
        uni.showToast({
          title: '保存失败，请重试',
          icon: 'none',
          duration: 2000
        })
      }
      this.$emit('error', error)
    },
    
    // 获取图片URL
    getImageUrl() {
      if (this.type === 'warehouse') {
        return this.data.thumbnailUrl || 
               this.data.coverImage || 
               this.data.image || 
               this.data.warehouseImage ||
               '/static/assets/warehouse/warehouse-default.jpg'
      } else {
        return this.data.thumbnailUrl || 
               this.data.parkImage || 
               this.data.image || 
               this.data.coverImage ||
               '/static/assets/park/park-default.jpg'
      }
    },
    
    // 获取标题
    getTitle() {
      if (this.type === 'warehouse') {
        return this.data.warehouseName || 
               this.data.name || 
               this.data.title ||
               '仓库名称'
      } else {
        return this.data.parkName || 
               this.data.name || 
               this.data.title ||
               '园区名称'
      }
    },
    
    // 获取地址
    getAddress() {
      if (this.type === 'warehouse') {
        return this.data.address || 
               this.data.location || 
               this.data.fullAddress ||
               '仓库地址'
      } else {
        return this.data.location || 
               this.data.address || 
               this.data.fullAddress ||
               '园区地址'
      }
    },
    
    // 获取价格
    getPrice() {
      return this.data.rentalPrice || 
             this.data.price || 
             this.data.rentPrice ||
             '0.9'
    },
    
    // 获取面积
    getArea() {
      if (this.type === 'warehouse') {
        return this.data.areaSize || 
               this.data.rentableArea || 
               this.data.area ||
               1000
      } else {
        return this.data.rentableArea || 
               this.data.areaSize || 
               this.data.area ||
               21000
      }
    },
    
    // 获取详细信息
    getDetailItems() {
      if (this.type === 'warehouse') {
        return [
          { 
            label: '仓库类型', 
            value: this.data.warehouseType?.typeName || 
                   this.data.warehouseType || 
                   this.data.type ||
                   '' 
          },
          { 
            label: '层高', 
            value: this.data.floorHeight || 
                   this.data.height ||
                   '' 
          },
          { 
            label: '地面承重', 
            value: this.data.floorLoad || 
                   this.data.loadCapacity ||
                   '' 
          },
          { 
            label: '月台数量', 
            value: (this.data.platformCount || 
                   this.data.platforms || 
                   '-') 
          }
        ]
      } else {
        return [
          { 
            label: '总占地面积', 
            value: this.formatArea(this.data.totalArea || 
                                  this.data.totalAreaSize || 
                                  0) 
          },
          { 
            label: '建筑面积', 
            value: this.formatArea(this.data.buildingArea || 
                                  this.data.buildingAreaSize || 
                                  0) 
          },
          { 
            label: '仓库类型', 
            value: this.data.warehouseType || 
                   this.data.type ||
                   '' 
          },
          { 
            label: '层高', 
            value: this.data.floorHeight || 
                   this.data.height ||
                   '' 
          }
        ]
      }
    },
    
    // 格式化面积
    formatArea(value) {
      const num = Number(value || 0)
      if (!num) return '0m²'
      if (num >= 100000) {
        const wan = num / 10000
        return `${this.toFixedSafe(wan, 0)}万m²`
      }
      return `${this.toFixedSafe(num, 0)}m²`
    },
    
    // 安全的toFixed方法
    toFixedSafe(n, d) {
      const m = Math.pow(10, d)
      return (Math.round(n * m) / m).toFixed(d)
    },
    
    // 清理缓存
    clearImageCache() {
      this.imageCache.clear()
    }
  },
  
  // 组件销毁时清理缓存
  beforeDestroy() {
    this.clearImageCache()
  }
}
</script>

<style scoped>
.poster-canvas {
  position: fixed;
  top: -9999px;
  left: -9999px;
  z-index: -1;
}
</style>
